import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr'

/**
 * 画线圈地游戏服务
 * 处理与后端的实时通信
 */
export class LineDrawingGameService {
  constructor() {
    this.connection = null
    this.gameId = null
    this.roomCode = null
    this.isConnected = false
    
    // 事件回调
    this.onRoomCreated = null
    this.onRoomJoined = null
    this.onGameStarted = null
    this.onPlayerJoined = null
    this.onPlayerLeft = null
    this.onPlayerConnectionUpdate = null
    this.onPlayerMoved = null
    this.onMoveRejected = null
    this.onDrawingStarted = null
    this.onPathPointAdded = null
    this.onTerritoryCompleted = null
    this.onPlayerDied = null
    this.onPlayerRespawned = null
    this.onPowerUpUsed = null
    this.onGameStateUpdate = null
    this.onRankingUpdate = null
    this.onError = null
    this.onDisconnected = null
  }

  /**
   * 连接到SignalR Hub
   */
  async connect(token) {
    try {
      this.connection = new HubConnectionBuilder()
        .withUrl('http://localhost:5128/lineDrawingGameHub', {
          accessTokenFactory: () => token
        })
        .withAutomaticReconnect()
        .configureLogging(LogLevel.Information)
        .build()

      // 设置事件监听器
      this.setupEventHandlers()

      await this.connection.start()
      this.isConnected = true
      console.log('Connected to LineDrawingGameHub')
    } catch (error) {
      console.error('Failed to connect to hub:', error)
      throw error
    }
  }

  /**
   * 断开连接
   */
  async disconnect() {
    if (this.connection) {
      await this.connection.stop()
      this.isConnected = false
      console.log('Disconnected from LineDrawingGameHub')
    }
  }

  /**
   * 设置事件处理器
   */
  setupEventHandlers() {
    // 房间创建
    this.connection.on('RoomCreated', (data) => {
      if (this.onRoomCreated) this.onRoomCreated(data)
    })

    // 房间加入
    this.connection.on('RoomJoined', (data) => {
      console.log('收到RoomJoined事件:', JSON.stringify(data, null, 2))
      if (this.onRoomJoined) this.onRoomJoined(data)
    })

    // 游戏开始
    this.connection.on('GameStarted', (data) => {
      if (this.onGameStarted) this.onGameStarted(data)
    })

    // 玩家加入
    this.connection.on('PlayerJoined', (data) => {
      if (this.onPlayerJoined) this.onPlayerJoined(data)
    })

    // 玩家离开
    this.connection.on('PlayerLeft', (data) => {
      if (this.onPlayerLeft) this.onPlayerLeft(data)
    })

    // 玩家连接状态更新
    this.connection.on('PlayerConnectionUpdate', (data) => {
      console.log('收到玩家连接状态更新:', data)
      if (this.onPlayerConnectionUpdate) this.onPlayerConnectionUpdate(data)
    })

    // 房间离开
    this.connection.on('RoomLeft', (data) => {
      console.log('Left room:', data)
    })

    // 玩家移动
    this.connection.on('PlayerMoved', (data) => {
      if (this.onPlayerMoved) this.onPlayerMoved(data)
    })

    // 移动被拒绝
    this.connection.on('MoveRejected', (data) => {
      console.warn('Move rejected:', data)
      console.warn('Move rejected errors:', data?.Errors || data?.errors)
      const errors = data?.Errors || data?.errors || ['未知错误']
      const errorMessage = Array.isArray(errors) ? errors.join(', ') : (errors || '移动被拒绝')
      console.warn('Move rejected message:', errorMessage)
      
      // 检查是否为死亡相关的移动被拒绝
      const isDeathRelated = errors.some(error => 
        error.includes('死亡') || error.includes('玩家状态无效') || error.includes('自撞')
      )
      
      if (isDeathRelated) {
        // 通知前端停止移动操作
        if (this.onMoveRejected) this.onMoveRejected(data)
      }
      
      if (this.onError) this.onError('移动被拒绝: ' + errorMessage)
    })

    // 开始画线
    this.connection.on('DrawingStarted', (data) => {
      if (this.onDrawingStarted) this.onDrawingStarted(data)
    })

    // 画线被拒绝
    this.connection.on('DrawingRejected', (data) => {
      console.warn('Drawing rejected:', data)
      const errors = data?.Errors || data?.errors || ['画线失败']
      const errorMessage = Array.isArray(errors) ? errors.join(', ') : (errors || '画线被拒绝')
      if (this.onError) this.onError('画线被拒绝: ' + errorMessage)
    })

    // 路径点添加
    this.connection.on('PathPointAdded', (data) => {
      if (this.onPathPointAdded) this.onPathPointAdded(data)
    })

    // 路径点被拒绝
    this.connection.on('PathPointRejected', (data) => {
      console.warn('Path point rejected:', data)
      const errors = data?.Errors || data?.errors || ['路径点添加失败']
      const errorMessage = Array.isArray(errors) ? errors.join(', ') : (errors || '路径点被拒绝')
      if (this.onError) this.onError('路径点被拒绝: ' + errorMessage)
    })

    // 圈地完成
    this.connection.on('TerritoryCompleted', (data) => {
      if (this.onTerritoryCompleted) this.onTerritoryCompleted(data)
    })

    // 圈地被拒绝
    this.connection.on('TerritoryRejected', (data) => {
      console.warn('Territory rejected:', data)
      const errors = data?.Errors || data?.errors || ['圈地失败']
      const errorMessage = Array.isArray(errors) ? errors.join(', ') : (errors || '圈地被拒绝')
      if (this.onError) this.onError('圈地被拒绝: ' + errorMessage)
    })

    // 玩家死亡
    this.connection.on('PlayerDied', (data) => {
      if (this.onPlayerDied) this.onPlayerDied(data)
    })

    // 玩家复活
    this.connection.on('PlayerRespawned', (data) => {
      if (this.onPlayerRespawned) this.onPlayerRespawned(data)
    })

    // 复活被拒绝
    this.connection.on('RespawnRejected', (data) => {
      console.warn('Respawn rejected:', data)
      const errors = data?.Errors || data?.errors || ['复活失败']
      const errorMessage = Array.isArray(errors) ? errors.join(', ') : (errors || '复活被拒绝')
      if (this.onError) this.onError('复活被拒绝: ' + errorMessage)
    })

    // 道具使用
    this.connection.on('PowerUpUsed', (data) => {
      if (this.onPowerUpUsed) this.onPowerUpUsed(data)
    })

    // 道具使用被拒绝
    this.connection.on('PowerUpRejected', (data) => {
      console.warn('PowerUp rejected:', data)
      const errors = data?.Errors || data?.errors || ['道具使用失败']
      const errorMessage = Array.isArray(errors) ? errors.join(', ') : (errors || '道具使用被拒绝')
      if (this.onError) this.onError('道具使用被拒绝: ' + errorMessage)
    })

    // 游戏状态更新
    this.connection.on('GameStateUpdate', (data) => {
      if (this.onGameStateUpdate) this.onGameStateUpdate(data)
    })

    // 排名更新
    this.connection.on('RankingUpdate', (data) => {
      if (this.onRankingUpdate) this.onRankingUpdate(data)
    })

    // 错误消息
    this.connection.on('Error', (message) => {
      if (this.onError) this.onError(message)
    })

    // 连接状态变化
    this.connection.onreconnecting(() => {
      console.log('Reconnecting...')
    })

    this.connection.onreconnected(() => {
      console.log('Reconnected')
      if (this.gameId) {
        this.joinGame(this.gameId) // 重新加入游戏
      }
    })

    this.connection.onclose(() => {
      console.log('Connection closed')
      this.isConnected = false
    })
  }

  /**
   * 加入游戏
   */
  async joinGame(gameId) {
    if (!this.isConnected) throw new Error('Not connected to hub')
    
    this.gameId = gameId
    await this.connection.invoke('JoinGame', gameId)
  }

  /**
   * 离开游戏
   */
  async leaveGame() {
    if (!this.isConnected || !this.gameId) return
    
    await this.connection.invoke('LeaveGame', this.gameId)
    this.gameId = null
  }

  /**
   * 玩家移动
   */
  async playerMove(x, y) {
    if (!this.isConnected || !this.gameId) return
    
    const timestamp = Date.now()
    await this.connection.invoke('PlayerMove', this.gameId, x, y, timestamp)
  }

  /**
   * 开始画线
   */
  async startDrawing(x, y) {
    if (!this.isConnected || !this.gameId) return
    
    const timestamp = Date.now()
    await this.connection.invoke('StartDrawing', this.gameId, x, y, timestamp)
  }

  /**
   * 添加路径点
   */
  async addPathPoint(x, y) {
    if (!this.isConnected || !this.gameId) return
    
    const timestamp = Date.now()
    await this.connection.invoke('AddPathPoint', this.gameId, x, y, timestamp)
  }

  /**
   * 完成画线
   */
  async completeDrawing(x, y) {
    if (!this.isConnected || !this.gameId) return
    
    const timestamp = Date.now()
    await this.connection.invoke('CompleteDrawing', this.gameId, x, y, timestamp)
  }

  /**
   * 使用道具
   */
  async usePowerUp(powerUpType) {
    if (!this.isConnected || !this.gameId) return
    
    const timestamp = Date.now()
    await this.connection.invoke('UsePowerUp', this.gameId, powerUpType, timestamp)
  }

  /**
   * 请求游戏状态
   */
  async requestGameState() {
    if (!this.isConnected || !this.gameId) return
    
    await this.connection.invoke('RequestGameState', this.gameId)
  }

  /**
   * 请求排名
   */
  async requestRanking() {
    if (!this.isConnected || !this.gameId) return
    
    await this.connection.invoke('RequestRanking', this.gameId)
  }

  /**
   * 玩家复活
   */
  async respawn() {
    if (!this.isConnected || !this.gameId) return
    
    await this.connection.invoke('Respawn', this.gameId)
  }

  // 房间管理方法

  /**
   * 创建游戏房间
   */
  async createRoom(roomCode, gameSettings) {
    if (!this.isConnected) {
      throw new Error('未连接到游戏服务器')
    }
    
    return new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        reject(new Error('创建房间超时'))
      }, 10000) // 10秒超时
      
      // 设置临时回调
      const originalCallback = this.onRoomCreated
      this.onRoomCreated = (data) => {
        clearTimeout(timeout)
        this.onRoomCreated = originalCallback
        
        if (data.Success) {
          this.gameId = data.GameId
          this.roomCode = data.RoomCode
          resolve(data)
        } else {
          reject(new Error(data.Errors?.join(', ') || '创建房间失败'))
        }
        
        // 恢复原始回调
        if (originalCallback) originalCallback(data)
      }
      
      // 调用SignalR方法
      this.connection.invoke('CreateRoom', roomCode, gameSettings)
        .catch(error => {
          clearTimeout(timeout)
          this.onRoomCreated = originalCallback
          reject(error)
        })
    })
  }

  /**
   * 加入游戏房间
   */
  async joinRoom(roomCode, playerId, playerName) {
    if (!this.isConnected) {
      throw new Error('未连接到游戏服务器')
    }
    
    return new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        reject(new Error('加入房间超时'))
      }, 10000) // 10秒超时
      
      // 设置临时回调
      const originalCallback = this.onRoomJoined
      this.onRoomJoined = (data) => {
        clearTimeout(timeout)
        this.onRoomJoined = originalCallback
        
        if (data.Success) {
          this.gameId = data.GameId
          this.roomCode = roomCode
          resolve(data)
        } else {
          reject(new Error(data.Errors?.join(', ') || '加入房间失败'))
        }
        
        // 恢复原始回调
        if (originalCallback) originalCallback(data)
      }
      
      // 调用SignalR方法
      console.log('调用JoinGame方法:', roomCode)
      this.connection.invoke('JoinGame', roomCode)
        .then(() => {
          console.log('JoinGame方法调用成功')
        })
        .catch(error => {
          console.error('JoinGame方法调用失败:', error)
          clearTimeout(timeout)
          this.onRoomJoined = originalCallback
          reject(error)
        })
    })
  }

  /**
   * 开始游戏
   */
  async startGame() {
    if (!this.isConnected || !this.gameId) {
      throw new Error('游戏状态无效')
    }
    
    return new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        reject(new Error('开始游戏超时'))
      }, 10000) // 10秒超时
      
      // 设置临时回调
      const originalCallback = this.onGameStarted
      this.onGameStarted = (data) => {
        clearTimeout(timeout)
        this.onGameStarted = originalCallback
        
        if (data.Success) {
          resolve(data)
        } else {
          reject(new Error(data.Errors?.join(', ') || '开始游戏失败'))
        }
        
        // 恢复原始回调
        if (originalCallback) originalCallback(data)
      }
      
      // 调用SignalR方法
      this.connection.invoke('StartGame', this.gameId)
        .catch(error => {
          clearTimeout(timeout)
          this.onGameStarted = originalCallback
          reject(error)
        })
    })
  }

  /**
   * 离开房间
   */
  async leaveRoom() {
    if (!this.isConnected || !this.gameId) {
      return { success: true }
    }
    
    try {
      await this.connection.invoke('LeaveRoom', this.gameId)
      
      // 重置状态
      this.gameId = null
      this.roomCode = null
      
      return { success: true }
    } catch (error) {
      console.error('离开房间失败:', error)
      return { success: false, error: error.message }
    }
  }

  /**
   * 更新游戏设置（房主专用）
   */
  async updateGameSettings(settings) {
    if (!this.isConnected || !this.gameId) {
      throw new Error('游戏状态无效')
    }
    
    await this.connection.invoke('UpdateGameSettings', this.gameId, settings)
  }
}

// 道具类型枚举
export const PowerUpType = {
  Lightning: 0, // 闪电
  Shield: 1,    // 护盾
  Bomb: 2,      // 炸弹
  Ghost: 3      // 幽灵
}

// 创建单例服务
export const lineDrawingGameService = new LineDrawingGameService()